package com.polaris.live.utils.fragment

import android.content.Context
import androidx.annotation.IdRes
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import com.polaris.live.common.util.ifDestroy

/**
 * FragmentUtils
 *
 * @author Created by lucas on 2023/10/28 14:10
 */
object FragmentUtils {

    /**
     * 获取FragmentManager
     */
    fun getFragmentManager(context: Context): FragmentManager? {
        return when (context) {
            is FragmentActivity -> {
                context.supportFragmentManager
            }

            else -> {
                null
            }
        }
    }

}

/**
 * 显示新的DialogFragment
 */
fun FragmentManager.showNewDialogFragment(fragment: DialogFragment, tag: String, owner: LifecycleOwner? = null) {
    val existingFragment = findFragmentByTag(tag)
    if (existingFragment is DialogFragment) {
        existingFragment.dismiss()
    }
    fragment.show(this, tag)

    owner?.ifDestroy {
        if (fragment.fragmentManager != null) {
            if (fragment.isAdded && !fragment.isStateSaved) {
                fragment.dismiss()
            } else {
                fragment.dismissAllowingStateLoss()
            }
        }
    }
}

/**
 * 附加fragment
 */
inline fun <reified F : Fragment> FragmentManager.attachFragment(
    @IdRes layoutId: Int,
    block: () -> F
): F {
    val lastFragment = findFragmentById(layoutId)?.let {
        if (it is F) {
            it
        } else {
            beginTransaction()
                .remove(it)
                .commit()

            null
        }
    }

    return lastFragment ?: block().also {
        beginTransaction()
            .add(layoutId, it)
            .commit()
    }
}

/**
 * 附加fragmentByTag
 */
inline fun <reified F : Fragment> FragmentManager.attachFragmentByTag(
    @IdRes layoutId: Int,
    tag: String,
    block: () -> F
): F {
    val lastFragment = findFragmentByTag(tag)?.let {
        if (it is F) {
            it
        } else {
            beginTransaction()
                .remove(it)
                .commit()
            null
        }
    }
    return lastFragment ?: block().also {
        beginTransaction()
            .add(layoutId, it, tag)
            .commit()
    }
}